/*    

    bobbietalk - a visual programming environment for toy robotics

    Copyright (C) 2013  Roberto Tiella

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
package bobbietalk.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.AttributedString;
import javax.swing.Icon;
import javax.swing.JButton;

/**
 *
 * @author roberto
 */
public class ShapedButton extends JButton {

    private boolean highlighted;
    private Shape shape;
    private final static Shape DEFAULT_SHAPE = new Rectangle(0, 0, 100, 100);
    private int iconOffsetX = 0;
    private int iconOffsetY = 0;

    {
        shape = DEFAULT_SHAPE;
        setBounds(shape.getBounds());

    }

    public int getIconOffsetX() {
        return iconOffsetX;
    }

    public void setIconOffsetX(int iconOffsetX) {
        this.iconOffsetX = iconOffsetX;
    }

    public int getIconOffsetY() {
        return iconOffsetY;
    }

    public void setIconOffsetY(int iconOffsetY) {
        this.iconOffsetY = iconOffsetY;
    }

    // Hit detection
    public Shape getShape() {
        return shape;
    }

    public void setShape(Shape shape) {
        this.shape = shape;


        setBounds(shape.getBounds());
        repaint();


    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(getBounds().width, getBounds().height);
    }

    public boolean isHighlighted() {
        return highlighted;
    }

    public void setHighlighted(boolean highlighted) {
        this.highlighted = highlighted;
    }

    @Override
    public boolean contains(int x, int y) {
        return this.shape.contains(x, y);
    }

    // paint the border
    protected void paintBorder(Graphics g) {
    }

    // paint the button
    @Override
    protected void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D) g;

        Color col = getBackground();

        if (highlighted) {
            col = col.brighter();
        }

        g2.setColor(col);
        g2.fill(this.shape);


        if (isSelected()) {

            g2.setColor(Color.YELLOW);


        } else {

            g2.setColor(Color.BLACK);

        }

        Stroke s = new BasicStroke(4);

        g2.setStroke(s);
        g2.draw(this.shape);

        if (false) {

            // draw extended bounds, used for debugging

            Rectangle b = this.getBounds();

            b.x = 0;
            b.y = 0;
            g2.draw(b);
        }

        Rectangle b = this.getBounds();

        int x = b.width / 2;
        int y = b.height / 2;

        Icon icon = getIcon();

        if (icon != null) {
            g2.setClip(shape);
            icon.paintIcon(this, g2, x - icon.getIconWidth() / 2 + getIconOffsetX(), 5 + getIconOffsetY());
        }

        // drawLabel(g2, b);


        final String label = getText();

        if (!label.isEmpty()) {

            String[] lines = label.split("@");

            int k = 0;

            for (String text : lines) {

                g2.drawString(text, (float) 10, (float) (b.height - 10 - (lines.length - k) * 15));
                k++;

            }

        }


    }

    private void drawLabel(Graphics2D g2, Rectangle b) {
        final Rectangle2D stringBounds = getFont().getStringBounds(getText(), g2.getFontRenderContext());

        g2.setColor(Color.WHITE);

        float sx = 10; // (float) (x - stringBounds.getCenterX());
        float sy = (float) (b.height - stringBounds.getHeight());//  (float) (y - stringBounds.getCenterY());

        TextLayout tl = new TextLayout(getText(), g2.getFont(), g2.getFontRenderContext());

        tl.draw(g2, sx, sy);
    }

    private void drawLabel2(final String label, Graphics2D g2, Rectangle b) {


        FontRenderContext frc = g2.getFontRenderContext();



        // let styledText be an AttributedCharacterIterator containing at least
        // one character


        String[] lines = label.split("|");

        int k = 0;

        for (String text : lines) {

            Point2D.Float pen = new Point2D.Float(5, b.height - 5 - (lines.length - k) * 10);

            k++;

            AttributedString as = new AttributedString(text);

            LineBreakMeasurer measurer = new LineBreakMeasurer(as.getIterator(), frc);
            float wrappingWidth = b.width;

            while (measurer.getPosition() < text.length()) {

                TextLayout layout = measurer.nextLayout(wrappingWidth);

                pen.y += (layout.getAscent());
                float dx = layout.isLeftToRight()
                        ? 0 : (wrappingWidth - layout.getAdvance());

                layout.draw(g2, (float) (pen.getX() + dx), (float) pen.getY());
                pen.y += layout.getDescent() + layout.getLeading();
            }

        }

    }
}
